package com.todo.event.activity.application.service.impl;

import com.todo.event.activity.application.convert.EventActivityRecordConvert;
import com.todo.event.activity.application.entity.bo.ActivityRecordBO;
import com.todo.event.activity.application.entity.bo.ActivityRewardRecordBO;
import com.todo.event.activity.application.entity.bo.ActivityTouchRecordBO;
import com.todo.event.activity.application.service.EventActivityRecordService;
import com.todo.event.activity.common.enums.EventActivityExecuteRewardEnum;
import com.todo.event.activity.common.enums.EventActivityExecuteTouchEnum;
import com.todo.event.activity.common.enums.ExecuteRecordStatusEnum;
import com.todo.event.activity.common.enums.RecordTypeEnum;
import com.todo.event.activity.infrastructure.entity.po.EventActivityRecordPO;
import com.todo.event.activity.infrastructure.entity.po.EventActivityRewardRecordPO;
import com.todo.event.activity.infrastructure.entity.po.EventActivityTouchRecordPO;
import com.todo.event.activity.infrastructure.repository.EventActivityRecordRepository;
import com.todo.event.activity.infrastructure.repository.EventActivityRewardRecordRepository;
import com.todo.event.activity.infrastructure.repository.EventActivityTouchRecordRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author azhebuxing
 * @date 2025/1/15 15:01
 * @description
 */
@Slf4j
@Service
public class EventActivityRecordServiceImpl implements EventActivityRecordService {

    @Resource
    private EventActivityRecordRepository eventActivityRecordRepository;
    @Resource
    private EventActivityRewardRecordRepository eventActivityRewardRecordRepository;
    @Resource
    private EventActivityTouchRecordRepository eventActivityTouchRecordRepository;

    @Override
    public Long insertActivityRecord(ActivityRecordBO activityRecordBO) {
        if (activityRecordBO == null) {
            return null;
        }
        EventActivityRecordPO eventActivityRecordPO = EventActivityRecordConvert.convertToEventActivityRecordPO(activityRecordBO);
        String uniqueKey = buildActivityRecordUK(activityRecordBO.getActivityId(), activityRecordBO.getUserId(), activityRecordBO.getUk());
        eventActivityRecordPO.setUk(uniqueKey);
        return eventActivityRecordRepository.insertActivityRecord(eventActivityRecordPO);
    }

    @Override
    public Long insertActivityRewardRecord(ActivityRewardRecordBO activityRewardRecordBO) {
        if (activityRewardRecordBO == null) {
            return null;
        }
        EventActivityRewardRecordPO eventActivityRewardRecordPO = EventActivityRecordConvert.convertToEventActivityRewardRecordPO(activityRewardRecordBO);
        String uniqueKey = buildActivityRewardRecordUK(activityRewardRecordBO.getActivityId(), activityRewardRecordBO.getUserId(), activityRewardRecordBO.getRewardType(), activityRewardRecordBO.getUk());
        eventActivityRewardRecordPO.setUk(uniqueKey);
        return eventActivityRewardRecordRepository.insertActivityRewardRecord(eventActivityRewardRecordPO) ? eventActivityRewardRecordPO.getId() : null;
    }

    @Override
    public Long insertActivityTouchRecord(ActivityTouchRecordBO activityTouchRecordBO) {
        if (activityTouchRecordBO == null) {
            return null;
        }
        EventActivityTouchRecordPO eventActivityTouchRecordPO = EventActivityRecordConvert.convertToEventActivityTouchRecordPO(activityTouchRecordBO);
        String uniqueKey = buildActivityTouchRecordUK(activityTouchRecordBO.getActivityId(), activityTouchRecordBO.getUserId(), activityTouchRecordBO.getTouchType(), activityTouchRecordBO.getUk());
        eventActivityTouchRecordPO.setUk(uniqueKey);
        return eventActivityTouchRecordRepository.insertActivityTouchRecord(eventActivityTouchRecordPO) ? eventActivityTouchRecordPO.getId() : null;
    }

    @Override
    public ActivityRecordBO queryActivityRecord(Long activityId, Long userId, String uk) {
        EventActivityRecordPO eventActivityRecordPO = eventActivityRecordRepository.queryRecordByActivityIdAndUK(activityId, buildActivityRecordUK(activityId, userId, uk));
        return eventActivityRecordPO == null ? null : EventActivityRecordConvert.convertToActivityRecordBO(eventActivityRecordPO);
    }

    @Override
    public ActivityRewardRecordBO queryRewardRecord(Long activityId, Long userId, EventActivityExecuteRewardEnum rewardEnum, String uk) {
        EventActivityRewardRecordPO eventActivityRewardRecordPO = eventActivityRewardRecordRepository.queryRecordByActivityIdAndUK(activityId, buildActivityRewardRecordUK(activityId, userId, rewardEnum, uk));
        return eventActivityRewardRecordPO == null ? null : EventActivityRecordConvert.convertToActivityRewardRecordBO(eventActivityRewardRecordPO);
    }

    @Override
    public ActivityTouchRecordBO queryTouchRecord(Long activityId, Long userId, EventActivityExecuteTouchEnum touchEnum, String uk) {
        EventActivityTouchRecordPO eventActivityTouchRecordPO = eventActivityTouchRecordRepository.queryRecordByActivityIdAndUK(activityId, buildActivityTouchRecordUK(activityId, userId, touchEnum, uk));
        return eventActivityTouchRecordPO == null ? null : EventActivityRecordConvert.convertToActivityTouchRecordBO(eventActivityTouchRecordPO);
    }

    @Override
    public List<ActivityRecordBO> queryActivityRecordListByIdList(List<Long> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return Collections.emptyList();
        }
        List<EventActivityRecordPO> eventActivityRecordPOS = eventActivityRecordRepository.queryRecordListByIdList(idList);
        if (CollectionUtils.isEmpty(eventActivityRecordPOS)) {
            return Collections.emptyList();
        }
        return eventActivityRecordPOS.stream().map(EventActivityRecordConvert::convertToActivityRecordBO).collect(Collectors.toList());
    }

    @Override
    public List<ActivityRewardRecordBO> queryRewardRecordListByIdList(List<Long> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return Collections.emptyList();
        }
        List<EventActivityRewardRecordPO> eventActivityRewardRecordPOS = eventActivityRewardRecordRepository.queryRecordListByIdList(idList);
        if (CollectionUtils.isEmpty(eventActivityRewardRecordPOS)) {
            return Collections.emptyList();
        }
        return eventActivityRewardRecordPOS.stream().map(EventActivityRecordConvert::convertToActivityRewardRecordBO).collect(Collectors.toList());
    }

    @Override
    public List<ActivityTouchRecordBO> queryRewardTouchListByIdList(List<Long> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return Collections.emptyList();
        }
        List<EventActivityTouchRecordPO> eventActivityTouchRecordPOS = eventActivityTouchRecordRepository.queryRecordListByIdList(idList);
        if (CollectionUtils.isEmpty(eventActivityTouchRecordPOS)) {
            return Collections.emptyList();
        }
        return eventActivityTouchRecordPOS.stream().map(EventActivityRecordConvert::convertToActivityTouchRecordBO).collect(Collectors.toList());
    }

    @Override
    public boolean updateActivityRecordStatus(RecordTypeEnum recordType, Long id, ExecuteRecordStatusEnum oldStatus, ExecuteRecordStatusEnum newStatus) {
        if (recordType == null || id == null || oldStatus == null || newStatus == null) {
            return false;
        }
        if (recordType == RecordTypeEnum.ACTIVITY) {
            return eventActivityRecordRepository.updateActivityRecordStatus(id, oldStatus, newStatus);
        } else if (recordType == RecordTypeEnum.REWARD) {
            return eventActivityRewardRecordRepository.updateActivityRewardRecordStatus(id, oldStatus, newStatus);
        } else if (recordType == RecordTypeEnum.TOUCH) {
            return eventActivityTouchRecordRepository.updateActivityTouchRecordStatus(id, oldStatus, newStatus);
        }
        return false;
    }

    @Override
    public List<Long> queryStatusRecordIdListByTime(RecordTypeEnum recordType, ExecuteRecordStatusEnum status, Date startTime, Date endTime) {
        if (recordType == null || status == null || startTime == null || endTime == null) {
            return Collections.emptyList();
        }
        if (recordType == RecordTypeEnum.ACTIVITY) {
            return eventActivityRecordRepository.queryStatusRecordIdListByTime(status, startTime, endTime);
        } else if (recordType == RecordTypeEnum.REWARD) {
            return eventActivityRewardRecordRepository.queryStatusRecordIdListByTime(status, startTime, endTime);
        } else if (recordType == RecordTypeEnum.TOUCH) {
            return eventActivityTouchRecordRepository.queryStatusRecordIdListByTime(status, startTime, endTime);
        }
        return Collections.emptyList();
    }

    @Override
    public boolean updateRecordBaseInfo(RecordTypeEnum recordType, Long recordId, String propertyCode, Integer retryCount, ExecuteRecordStatusEnum recordStatus) {
        if (recordType == null || recordId == null){
            return false;
        }
        if (recordType == RecordTypeEnum.ACTIVITY) {
            return eventActivityRecordRepository.updateActivityRecordBaseInfo(recordId, retryCount, recordStatus);
        } else if (recordType == RecordTypeEnum.REWARD) {
            return eventActivityRewardRecordRepository.updateActivityRewardRecordBaseInfo(recordId, propertyCode, retryCount, recordStatus);
        } else if (recordType == RecordTypeEnum.TOUCH) {
            return eventActivityTouchRecordRepository.updateActivityTouchRecordBaseInfo(recordId, propertyCode, retryCount, recordStatus);
        }
        return false;
    }

    private String buildActivityRecordUK(Long activityId, Long userId, String uk) {
        return activityId + "_" + userId + "_" + uk;
    }

    private String buildActivityRewardRecordUK(Long activityId, Long userId, EventActivityExecuteRewardEnum rewardType, String uk) {
        return activityId + "_" + userId + "_" + uk + "_" + rewardType.getType();
    }

    private String buildActivityTouchRecordUK(Long activityId, Long userId, EventActivityExecuteTouchEnum touchType, String uk) {
        return activityId + "_" + userId + "_" + uk + "_" + touchType.getType();
    }
}
